<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>黑客帝国 LOVE</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background: #000;
        }
        canvas {
            display: block;
            position: absolute;
            top: 0;
            left: 0;
        }
        #canvas {
            z-index: 1;
        }
        #pinkboard {
            width: 100%;
            height: 100%;
            opacity: 0;
            transition: opacity 1s ease-in-out;
            z-index: 2;
        }
        #love-text {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 24px;
            font-family: "Microsoft YaHei", sans-serif;
            font-style: italic;
            background: linear-gradient(45deg, #87CEEB, #1E90FF);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            text-shadow: 0 0 10px rgba(135, 206, 235, 0.5);
            z-index: 3;
            opacity: 0;
            transition: opacity 1s ease-in-out;
            animation: glow 2s ease-in-out infinite;
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 8px;
        }
        .love-line {
            display: flex;
            justify-content: center;
            align-items: baseline;
            padding: 0 10px;
            gap: 0;
        }
        .love-line:nth-child(1) {
            word-spacing: normal;
        }
        .love-line:nth-child(2) {
            word-spacing: 15px;
        }
        @keyframes glow {
            0% { text-shadow: 0 0 10px rgba(135, 206, 235, 0.5); }
            50% { text-shadow: 0 0 20px rgba(135, 206, 235, 0.8), 0 0 30px rgba(30, 144, 255, 0.6); }
            100% { text-shadow: 0 0 10px rgba(135, 206, 235, 0.5); }
        }
        .love-line:nth-child(1) span {
            margin-right: 3px;
        }
        .love-line:nth-child(1) span.dots {
            margin-right: 2px;
        }
        .love-line:nth-child(1) span:first-child {
            margin-right: 35px;
        }
        .love-line:nth-child(1) span:last-child {
            margin-right: 0;
        }
        .love-line:nth-child(1) span.dots:last-of-type {
            margin-right: 8px;
        }
        .love-line:nth-child(1) span.dots {
            visibility: hidden;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <canvas id="pinkboard"></canvas>
    <div id="love-text">
        <div class="love-line">
            <span>清</span><span class="dots">·</span><span class="dots">·</span><span class="dots">·</span><span class="dots">·</span><span class="dots">·</span><span class="dots">·</span><span class="dots">·</span><span class="dots">·</span><span>清</span>
        </div>
        <div class="love-line">我 爱</div>
        <div class="love-line">你</div>
    </div>
    <script>
        // 黑客帝国特效代码
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');

        // 设置画布尺寸
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        // 字符集
        const chars = ['L', 'O', 'V', 'E', 'LOVE', '❤️', '清清'];
        const verticalLove = 'LOVE';
        const fontSize = 14;
        const columns = Math.floor(canvas.width / fontSize);
        const drops = [];
        const columnFontSizes = [];
        const charWidths = {
            'L': 1, 'O': 1, 'V': 1, 'E': 1, 'LOVE': 4, '❤️': 1, '清清': 2
        };

        function getRandomFontSize() {
            if (Math.random() < 0.52) {
                return fontSize * (1 + Math.random() * 2);
            }
            return fontSize;
        }

        function getRandomChar() {
             const singleChars = ['L', 'O', 'V', 'E', '❤️'];
             return singleChars[Math.floor(Math.random() * singleChars.length)];
        }

        for (let i = 0; i < columns; i++) {
            drops[i] = Math.floor(Math.random() * -canvas.height);
            columnFontSizes[i] = getRandomFontSize();
        }

        function draw() {
            ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            ctx.font = fontSize + 'px monospace';
            
            for (let i = 0; i < drops.length; i++) {
                const char = chars[Math.floor(Math.random() * chars.length)];
                const x = i * fontSize;
                const y = drops[i] * fontSize;
                const currentFontSize = columnFontSizes[i];
                ctx.font = currentFontSize + 'px monospace';
                
                if (currentFontSize > fontSize * 2) {
                    ctx.shadowBlur = 0;
                } else {
                    ctx.shadowBlur = 15;
                    ctx.shadowColor = '#FF69B4';
                }
                
                ctx.fillStyle = '#FF69B4';
                
                if (char === 'LOVE') {
                    for (let j = 0; j < verticalLove.length; j++) {
                        ctx.fillText(verticalLove[j], x, y + j * currentFontSize);
                    }
                } else if (char === '清清') {
                    const qingqing = '清清';
                    for (let j = 0; j < qingqing.length; j++) {
                        ctx.fillText(qingqing[j], x - currentFontSize * 0.4, y + j * currentFontSize);
                    }
                } else {
                    ctx.fillText(char, x, y);
                }

                ctx.shadowBlur = 0;
                ctx.font = fontSize + 'px monospace';

                if (y > canvas.height && Math.random() > 0.975) {
                    drops[i] = 0;
                    columnFontSizes[i] = getRandomFontSize();
                }

                drops[i]++;
            }
        }

        setInterval(draw, 33);

        window.addEventListener('resize', () => {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
            const columns = Math.floor(canvas.width / fontSize);
            drops.length = 0;
            for (let i = 0; i < columns; i++) {
                drops[i] = Math.floor(Math.random() * -canvas.height);
            }
        });

        // 李洵特效代码
        var settings = {
            particles: {
                length: 800,
                duration: 4,
                velocity: 100,
                effect: -0.75,
                size: 35,
            },
        };

        (function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());

        var Point = (function() {
            function Point(x, y) {
                this.x = (typeof x !== 'undefined') ? x : 0;
                this.y = (typeof y !== 'undefined') ? y : 0;
            }
            Point.prototype.clone = function() {
                return new Point(this.x, this.y);
            };
            Point.prototype.length = function(length) {
                if (typeof length == 'undefined')
                    return Math.sqrt(this.x * this.x + this.y * this.y);
                this.normalize();
                this.x *= length;
                this.y *= length;
                return this;
            };
            Point.prototype.normalize = function() {
                var length = this.length();
                this.x /= length;
                this.y /= length;
                return this;
            };
            return Point;
        })();

        var Particle = (function() {
            function Particle() {
                this.position = new Point();
                this.velocity = new Point();
                this.acceleration = new Point();
                this.age = 0;
            }
            Particle.prototype.initialize = function(x, y, dx, dy) {
                this.position.x = x;
                this.position.y = y;
                this.velocity.x = dx;
                this.velocity.y = dy;
                this.acceleration.x = dx * settings.particles.effect;
                this.acceleration.y = dy * settings.particles.effect;
                this.age = 0;
            };
            Particle.prototype.update = function(deltaTime) {
                this.position.x += this.velocity.x * deltaTime;
                this.position.y += this.velocity.y * deltaTime;
                this.velocity.x += this.acceleration.x * deltaTime;
                this.velocity.y += this.acceleration.y * deltaTime;
                this.age += deltaTime;
            };
            Particle.prototype.draw = function(context, image) {
                function ease(t) {
                    return (--t) * t * t + 1;
                }
                var size = image.width * ease(this.age / settings.particles.duration);
                context.globalAlpha = 1 - this.age / settings.particles.duration;
                context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);
            };
            return Particle;
        })();

        var ParticlePool = (function() {
            var particles,
                firstActive = 0,
                firstFree = 0,
                duration = settings.particles.duration;
            
            function ParticlePool(length) {
                particles = new Array(length);
                for (var i = 0; i < particles.length; i++)
                    particles[i] = new Particle();
            }
            ParticlePool.prototype.add = function(x, y, dx, dy) {
                particles[firstFree].initialize(x, y, dx, dy);
                firstFree++;
                if (firstFree == particles.length) firstFree = 0;
                if (firstActive == firstFree) firstActive++;
                if (firstActive == particles.length) firstActive = 0;
            };
            ParticlePool.prototype.update = function(deltaTime) {
                var i;
                if (firstActive < firstFree) {
                    for (i = firstActive; i < firstFree; i++)
                        particles[i].update(deltaTime);
                }
                if (firstFree < firstActive) {
                    for (i = firstActive; i < particles.length; i++)
                        particles[i].update(deltaTime);
                    for (i = 0; i < firstFree; i++)
                        particles[i].update(deltaTime);
                }
                while (particles[firstActive].age >= duration && firstActive != firstFree) {
                    firstActive++;
                    if (firstActive == particles.length) firstActive = 0;
                }
            };
            ParticlePool.prototype.draw = function(context, image) {
                if (firstActive < firstFree) {
                    for (i = firstActive; i < firstFree; i++)
                        particles[i].draw(context, image);
                }
                if (firstFree < firstActive) {
                    for (i = firstActive; i < particles.length; i++)
                        particles[i].draw(context, image);
                    for (i = 0; i < firstFree; i++)
                        particles[i].draw(context, image);
                }
            };
            return ParticlePool;
        })();

        // 5秒后启动心形特效和文字
        setTimeout(function() {
            document.getElementById('pinkboard').style.opacity = '1';
            
            (function(canvas) {
                var context = canvas.getContext('2d'),
                    particles = new ParticlePool(settings.particles.length),
                    particleRate = settings.particles.length / settings.particles.duration,
                    time;
                
                function pointOnHeart(t) {
                    return new Point(
                        160 * Math.pow(Math.sin(t), 3),
                        130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25
                    );
                }
                
                var image = (function() {
                    var canvas = document.createElement('canvas'),
                        context = canvas.getContext('2d');
                    canvas.width = settings.particles.size;
                    canvas.height = settings.particles.size;
                    
                    function to(t) {
                        var point = pointOnHeart(t);
                        point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;
                        point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;
                        return point;
                    }
                    
                    context.beginPath();
                    var t = -Math.PI;
                    var point = to(t);
                    context.moveTo(point.x, point.y);
                    while (t < Math.PI) {
                        t += 0.01;
                        point = to(t);
                        context.lineTo(point.x, point.y);
                    }
                    context.closePath();
                    context.fillStyle = '#FF69B4';
                    context.fill();
                    var image = new Image();
                    image.src = canvas.toDataURL();
                    return image;
                })();
                
                function render() {
                    requestAnimationFrame(render);
                    var newTime = new Date().getTime() / 1000,
                        deltaTime = newTime - (time || newTime);
                    time = newTime;
                    
                    context.clearRect(0, 0, canvas.width, canvas.height);
                    
                    var amount = particleRate * deltaTime;
                    for (var i = 0; i < amount; i++) {
                        var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
                        var dir = pos.clone().length(settings.particles.velocity);
                        particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);
                    }
                    
                    particles.update(deltaTime);
                    particles.draw(context, image);
                }
                
                function onResize() {
                    canvas.width = canvas.clientWidth;
                    canvas.height = canvas.clientHeight;
                }
                window.onresize = onResize;
                
                onResize();
                render();
            })(document.getElementById('pinkboard'));
        }, 5000);

        // 文字延迟1秒出现
        setTimeout(function() {
            document.getElementById('love-text').style.opacity = '1';
        }, 7000);
    </script>
</body>
</html> 